package com.pie4cloud.pie.job.biz.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.pie4cloud.pie.job.api.dto.*;
import com.pie4cloud.pie.job.biz.util.Md5Encrypt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
@Slf4j
public class PortalService {
    private RestTemplate restTemplate = new RestTemplate();
    @Value("${sod.url}")
    private String sodUrl;
    @Value("${sod.pwd}")
    private String sodPwd;

	@Value("${sod.api.database}")
	private String databaseApi;

	@Value("${sod.api.dataTable}")
	private String dataTableApi;

	@Value("${sod.api.findTablesByName}")
	private String findTablesByName;


    public String sendSodGetRequest(DataRegister dataRegister){
        try {
            //调用存储申请
            String sodDataInfo = dataRegister.getSodDataInfo();

            Map<String, Object> sodSign = this.getSodSign(sodDataInfo);

            String url = sodUrl+dataRegister.getUrl();

            //拼接参数
            String sendstr ="pwd="+sodPwd+"&";
            for(Map.Entry<String, Object> entry:sodSign.entrySet()) {
                if(!"data".equals(entry.getKey())){
                    sendstr=sendstr+entry.getKey()+"="+entry.getValue()+"&";
                }else {
                    if("".equals(String.valueOf(entry.getValue()))){
                    }else {
                        sendstr=sendstr+entry.getKey()+"={data}&";
                    }

                }

            }
            sendstr=sendstr.substring(0,sendstr.length()-1);
            //生成url
            if(url.contains("?")){
                url = url + "&" + sendstr;
            }else{
                url = url + "?" + sendstr;
            }

            String resultStr = doGet(url,sodDataInfo);
            return resultStr;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public String sendSodPostRequest(DataRegister dataRegister){
        try {
            //调用存储申请
            String sodDataInfo = dataRegister.getSodDataInfo();
            sodDataInfo = sodDataInfo.replaceAll(":null", ":\"\"");
            JSONObject resultObject = JSON.parseObject(sodDataInfo, JSONObject.class);
            //resultObject.put("id", dataRegister.getId());
            sodDataInfo = JSON.toJSONString(resultObject);

            Map<String, Object> sodSign = this.getSodSign(sodDataInfo);

            String url = sodUrl+dataRegister.getUrl();
            String resultStr = this.doPost(url, JSON.toJSONString(sodSign));
            return resultStr;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    public Map<String,Object> getSodSign(String paramData){

        List<String> paramSign = new ArrayList<>();
        Map<String,Object> paramMapq = new HashMap<>();
        String timestamp = new Date().getTime() + "";
        String nonce = UUID.randomUUID().toString().replace("-","");
        if(!StringUtils.isEmpty(paramData)){
            paramSign.add("data"+"="+paramData);
        }
        paramSign.add("interfaceId"+"=sod");
        paramSign.add("nonce"+"="+nonce);
        paramSign.add("timestamp"+"="+timestamp);
        paramSign.add("userId"+"=api_manager");
        String sign = this.calSign(paramSign, "api_manager");
        if(!StringUtils.isEmpty(paramData)){
            paramMapq.put("data", paramData);
        }
        paramMapq.put("interfaceId", "sod");
        paramMapq.put("nonce", nonce);
        paramMapq.put("timestamp", timestamp);
        paramMapq.put("userId", "api_manager");
        paramMapq.put("sign",sign);
        return paramMapq;
    }
    public String calSign(List<String> paramList,String userId){
        String sign = "";
        try {
            //拼接密码

            //String pwd = new String(Base64.getDecoder().decode(encPwd.getPwd().getBytes()), "UTF-8");
            paramList.add("pwd="+sodPwd);
            //参数排序
            Collections.sort(paramList);
            String paramStr = StringUtils.join(paramList,"&");
            log.info("计算前字符串："+paramStr);

            //生成sign
            sign = Md5Encrypt.generatePassword(paramStr);
            log.info(">>>>>>>>>>sign 生成成功 :"+sign);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sign;
    }

    public static String doPost(String url,String params) {

        String resultStr = null;
        Map resultMap = new HashMap<>();
        CloseableHttpClient client = null;
        CloseableHttpResponse response = null;
        try {
            client = HttpClients.createDefault();
            //创建post请求
            HttpPost request = new HttpPost(url);

            request.setHeader("Accept","application/json");
            request.setHeader("Content-Type","application/json");

            StringEntity paramEntity = new StringEntity(params,"UTF-8");
            request.setEntity(paramEntity);

            //设置请求超时时间
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(60*1000).setConnectTimeout(60*1000).build();

            request.setConfig(requestConfig);
            log.info("开始发送post请求,请求地址 : "+url + "  请求参数 : "+params);
            response = client.execute(request);
            resultStr = EntityUtils.toString(response.getEntity());

            //请求成功
            if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                log.info("post请求发送成功 ,请求地址 :"+url);
            }else {
                log.error("post请求发送失败 :"+response.getStatusLine().getStatusCode()+" ,请求地址 :"+url+" ,返回结果"+resultStr);
                resultMap.put("success", false);
                resultMap.put("code", response.getStatusLine().getStatusCode());
                resultMap.put("msg", resultStr);
                resultStr = JSON.toJSONString(resultMap);
            }

        } catch (Exception e) {
            log.error("post请求发送失败 : "+url+" ;异常信息 :"+e.getMessage());
            resultMap.put("success", false);
            resultMap.put("code", response == null?null:response.getStatusLine().getStatusCode());
            resultMap.put("msg", e.getMessage());
            resultStr = JSON.toJSONString(resultMap);
        } finally {
            try {
                if(null != client) {
                    client.close();
                }
                if(null != response) {
                    response.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }

        return resultStr;
    }
    public  String doGet(String url,String data) {

        String resultStr = null;
        ResponseEntity<String> res = null;
        try {
            if(!StringUtils.isEmpty(data)){
                res = restTemplate.getForEntity(url,String.class,data);
            }else {
                res = restTemplate.getForEntity(url,String.class);
            }
            resultStr = res.getBody();
        } catch (RestClientException e) {
            e.printStackTrace();
        }

        return resultStr;
    }

    public SodCallResult<SodPage<SodTable>> loadTablesByName(String databaseId, String tableName) {
		DataRegister dataRegister = new DataRegister();
		Map<String,String> map = new HashMap<>();
		map.put("databaseId",databaseId);
		map.put("tableName",tableName);
		dataRegister.setSodDataInfo(JSON.toJSONString(map));
		dataRegister.setUrl(findTablesByName);
		String result = sendSodGetRequest(dataRegister);
		ObjectMapper objectMapper = new ObjectMapper();
		JavaType sodPageType = objectMapper.getTypeFactory().constructParametricType(SodPage.class, SodTable.class);
		JavaType sodCallReslutType = objectMapper.getTypeFactory().constructParametricType(SodCallResult.class, sodPageType);
		try {
			return objectMapper.readValue(result, sodCallReslutType);
		} catch (JsonProcessingException e) {
			return null;
		}
	}

	public SodCallResult<TableDetailInfo> getTableInfoByTableId(String tableId) throws JsonProcessingException {
		DataRegister dataRegister = new DataRegister();
		Map<String,String> map = new HashMap<>();
		map.put("id",tableId);
		dataRegister.setSodDataInfo(JSON.toJSONString(map));
		dataRegister.setUrl(dataTableApi);
		String result = sendSodGetRequest(dataRegister);
		ObjectMapper objectMapper = new ObjectMapper();
		TypeFactory typeFactory = objectMapper.getTypeFactory();
		JavaType javaType = typeFactory.constructParametricType(SodCallResult.class, TableDetailInfo.class);
		return  objectMapper.readValue(result, javaType);
	}

	public SodCallResult<TableDetailInfo> getTableInfoByDatabaseIdAndTableName(String dataBaseId,String tableName) throws JsonProcessingException {

		SodCallResult<SodPage<SodTable>> sodPageSodCallResult = loadTablesByName(dataBaseId, tableName);
		if(sodPageSodCallResult.getSuccess()) {
			SodPage<SodTable> sodPage = sodPageSodCallResult.getData();
			if (sodPage.getTotalCount() >= 1 && sodPage.getPageData().size() >= 1) {
				SodTable sodTable = sodPage.getPageData().get(0);
				return getTableInfoByTableId(sodTable.getTableId());
			}
		}
		return null;
	}

	public void getDataBaseInfo(String dataBaseId) {
		DataRegister dataRegister = new DataRegister();
		Map<String,String> map = new HashMap<>();
		map.put("id",dataBaseId);
		dataRegister.setSodDataInfo(JSON.toJSONString(map));
		dataRegister.setUrl(databaseApi);
		String result = sendSodGetRequest(dataRegister);
		ObjectMapper objectMapper = new ObjectMapper();
		TypeFactory typeFactory = objectMapper.getTypeFactory();
		JavaType javaType = typeFactory.constructParametricType(SodCallResult.class, DataBaseInfo.class);
		try {
			SodCallResult<DataBaseInfo> sodCallResult = objectMapper.readValue(result, javaType);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws JsonProcessingException {
//		PortalService portalService = new PortalService();
//		portalService.getTableInfoByDatabaseIdAndTableName("06eadd4476b94b36985e1460de268cbe", "SATE_PRODUCT_PART1_FILE_TAB");

		System.out.println(StringUtils.contains("USR_SOD.SATE_PRODUCT_PART1_FILE_TAB","."));
		System.out.println(StringUtils.split("USR_SOD.SATE_PRODUCT_PART1_FILE_TAB",".")[0]);
	}
}
